home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
MCASM.RAR
/
MC_ASM.EXE
/
WROX_ASM
/
CH12
/
COMMON
/
PALETTE.H
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-24
|
7KB
|
173 lines
#ifndef palette_h
#define palette_h
/*
* The Color Quantization : true color to 256 or
* to smaller (specified) colors palette
*
* Most of code and ideas were taken
* from the Independent JPEG Group's software.
* ( see the accompanying README file).
*
* I just adjust code for RGB color model (instead of YCbCr)
* and re-organized text
* to fit our class library and
* to avoid duplication of code in similar procedures
* (but it all is not good for execution speed)
* and make some (unimportant) changes ....
* (and maybe brought some buggs)
*
* E.Podvoysky from ^Z for WROX press book
*
*/
/*
* This module implements the well-known Heckbert paradigm for color
* quantization. Most of the ideas used here can be traced back to
* Heckbert's seminal paper
* Heckbert, Paul. "Color Image Quantization for Frame Buffer Display",
* Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304.
*
* In the first pass over the image, we accumulate a histogram showing the
* usage count of each possible color. (To keep the histogram to a reasonable
* size, we reduce the precision of the input; typical practice is to retain
* 5 or 6 bits per color, so that 8 or 4 different input values are counted
* in the same histogram cell.) Next, the color-selection step begins with a
* box representing the whole color space, and repeatedly splits the "largest"
* remaining box until we have as many boxes as desired colors. Then the mean
* color in each remaining box becomes one of the possible output colors.
* The second pass over the image maps each input pixel to the closest output
* color (optionally after applying a Floyd-Steinberg dithering correction).
* This mapping is logically trivial, but making it go fast enough requires
* considerable care.
*
* Heckbert-style quantizers vary a good deal in their policies for choosing
* the "largest" box and deciding where to cut it. The particular policies
* used here have proved out well in experimental comparisons, but better ones
* may yet be found.
*
* The most significant difference between this quantizer and others is that
* this one is intended to operate in YCbCr colorspace, rather than RGB space
* as is usually done. Actually we work in scaled YCbCr colorspace, where
* Y distances are inflated by a factor of 2 relative to Cb or Cr distances.
* The empirical evidence is that distances in this space correspond to
* perceptual color differences more closely than do distances in RGB space;
* and working in this space is inexpensive within a JPEG decompressor, since
* the input data is already in YCbCr form. (We could transform to an even
* more perceptually linear space such as Lab or Luv, but that is very slow
* and doesn't yield much better results than scaled YCbCr.)
*/
#ifdef INT_MAP_CELL
#define MAXNUMCOLORS 256 /* maximum size of colormap */
#else
#define MAXNUMCOLORS 255 /* maximum size of colormap */
#endif
/*
* First we have the histogram data structure and routines for creating it.
*
* For work in YCbCr space, it is useful to keep more precision for Y than
* for Cb or Cr. We recommend keeping 6 bits for Y and 5 bits each for Cb/Cr.
* If you have plenty of memory and cycles, 6 bits all around gives marginally
* better results; if you are short of memory, 5 bits all around will save
* some space but degrade the results.
* To maintain a fully accurate histogram, we'd need to allocate a "long"
* (preferably unsigned long) for each cell. In practice this is overkill;
* we can get by with 16 bits per cell. Few of the cell counts will overflow,
* and clamping those that do overflow to the maximum value will give close-
* enough results. This reduces the recommended histogram size from 256Kb
* to 128Kb, which is a useful savings on PC-class machines.
* (In the second pass the histogram space is re-used for pixel mapping data;
* in that capacity, each cell must be able to store zero to the number of
* desired colors. 16 bits/cell is plenty for that too.)
* Since the JPEG code is intended to run in small memory model on 80x86
* machines, we can't just allocate the histogram in one chunk. Instead
* of a true 3-D array, we use a row of pointers to 2-D arrays.
*
* (From hence comment is slightly changed according RGB color model - E.P.)
* Each pointer corresponds to a R value (typically 2^5 = 32 pointers) and
* each 2-D array has 2^(5+5) = 1024 or 2^(6+5) = 2048 entries. Note that
* on 80x86 machines, the pointer row may be in near memory but the actual
* arrays are in far memory.
*/
#define HIST_G_BITS 6 /* bits of precision in G histogram */
#define HIST_R_BITS 5 /* bits of precision in R histogram */
#define HIST_B_BITS 5 /* bits of precision in B histogram */
// #define Y_SCALE 2 /* scale Y distances up by this much */
#define RSCALE 24 /* E.P.- scale G distances up by this much and / 16*/
#define GSCALE 32 /* E.P.- scale R distances up by this much and / 16*/
#define HIST_G_ELEMS (1<<HIST_G_BITS) /* # of elements along histogram axes */
#define HIST_R_ELEMS (1<<HIST_R_BITS)
#define HIST_B_ELEMS (1<<HIST_B_BITS)
#define G_SHIFT (8 - HIST_G_BITS)
#define R_SHIFT (8 - HIST_R_BITS)
#define B_SHIFT (8 - HIST_B_BITS)
//------------------------- HISTOGRAM
typedef WORD histcell; /* histogram cell; MUST be an unsigned type */
typedef histcell far *histptr; /* for pointers to histogram cells */
typedef histcell hist1d[HIST_B_ELEMS]; /* typedefs for the array */
typedef hist1d far * hist2d; /* type for the R-level pointers */
typedef hist2d * hist3d; /* type for top-level pointer */
//------------------------- BOX
typedef struct {
/* The bounds of the box (inclusive); expressed as histogram indexes */
int c0min, c0max;
int c1min, c1max;
int c2min, c2max;
/* The number of nonzero histogram cells within this box */
unsigned long colorcount,
//this was added by E.P.
volume;
BOOL splitable;
} box;
typedef box *boxptr;
class color_selector {
protected:
hist3d histogram; /* pointer to the histogram */
boxptr boxlist; /* array with room for desired # of boxes */
int numboxes; /* number of boxes currently in boxlist */
// first stage
boxptr find_biggest_color_pop ();
boxptr find_biggest_volume ();
void update_box (boxptr boxp);
void compute_color (boxptr boxp, BGRcolortype &color);
void median_cut (); /* Repeatedly select and split the largest box
/* until we have enough boxes */
public:
BGRpalette my_colormap; /* the finished colormap (in RGB space) */
int desired_colors,actual_number_of_colors,width;
BOOL initialized;
color_selector(int desired_colors_,int width_); //allocate create histogram and
virtual ~color_selector();
void prescan_line (BYTE *R, BYTE *G, BYTE *B);
void select_colors();
// special procedures to convert 256 colors to 16
void prepare_scan_palette (BGRpalette pal);
void prescan_line_palette (BYTE *source);
};
#endif